package com.bwie.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bwie.domain.Price;
import com.bwie.domain.PriceDetail;
import com.bwie.domain.Shop;
import com.bwie.es.EsShop;
import com.bwie.mapper.PriceDetailMapper;
import com.bwie.mapper.PriceMapper;
import com.bwie.mapper.ShopMapper;
import com.bwie.service.PriceService;
import com.bwie.utils.R;
import com.bwie.vo.AddPriceVo;
import com.bwie.vo.PageInfoVo;
import com.bwie.vo.PriceInfoVo;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.HighlightQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.Acknowledgment;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * @Author: lrz
 * @Date: 2024/10/31 17:42
 * @Description:
 **/
@Service
public class PriceServiceImpl implements PriceService {


    @Autowired
    PriceMapper priceMapper;

    @Autowired
    PriceDetailMapper priceDetailMapper;

    @Autowired
    ShopMapper shopMapper;

    @Autowired
    HttpServletRequest request;

    @Autowired
    ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Autowired
    KafkaTemplate kafkaTemplate;
    @Override
    public R shopListEs(PageInfoVo pageInfoVo) {

        Integer pageNum =0;
        if(pageInfoVo.getPageNum()>0){
            pageNum = pageInfoVo.getPageNum()-1;
        }
        PageRequest pageRequest = PageRequest.of(pageNum, pageInfoVo.getPageSize());

        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        if(StringUtils.isNotEmpty(pageInfoVo.getKeyWord())){
            boolQueryBuilder.should(QueryBuilders.matchQuery("txm",pageInfoVo.getKeyWord()));
            boolQueryBuilder.should(QueryBuilders.matchQuery("name",pageInfoVo.getKeyWord()));
        }

        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("name").preTags("<font color='red'>").postTags("</font>");

        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        nativeSearchQueryBuilder.withPageable(pageRequest)
                .withQuery(boolQueryBuilder)
                .withHighlightBuilder(highlightBuilder);

        SearchHits<EsShop> search = elasticsearchRestTemplate.search(nativeSearchQueryBuilder.build(), EsShop.class);

        Long total = search.getTotalHits();
        ArrayList<EsShop> esShops = new ArrayList<>();
        for (SearchHit<EsShop> searchHit : search.getSearchHits()) {
            EsShop content = searchHit.getContent();

            List<String> name = searchHit.getHighlightField("name");
            if(name!=null && name.size()>0){
                content.setName(name.get(0));
            }

            esShops.add(content);
        }

        HashMap<String, Object> hashMap = new HashMap<>();

        hashMap.put("total",total);
        hashMap.put("records",esShops);

        return R.OK(hashMap);
    }

    @Override
    public R priceList(PageInfoVo pageInfoVo) {
        Page<Price> pricePage = new Page<>(pageInfoVo.getPageNum(), pageInfoVo.getPageSize());
        QueryWrapper<Price> priceQueryWrapper = new QueryWrapper<>();
        priceQueryWrapper.orderByDesc("sq_time");
        Page<Price> pricePage1 = priceMapper.selectPage(pricePage, priceQueryWrapper);
        return R.OK(pricePage1);
    }

    @Override
    public R addPrice(AddPriceVo addPriceVo) {

        String token = request.getHeader("token");
        Claims body = Jwts.parser().setSigningKey("123456").parseClaimsJws(token).getBody();
        Integer userId = body.get("userId",Integer.class);
        String username = body.get("userName", String.class);

        //添加调价单
        Price price = addPriceVo.getPrice();
        price.setDh("LSJ"+System.currentTimeMillis());
        price.setSqTime(new Date());
        price.setUserId(userId);
        price.setUsername(username);
        price.setTxm("1234");
        price.setFlagId(0);

        priceMapper.insert(price);


        //添加调价单明细
        List<Shop> shopList = addPriceVo.getShopList();
        Double zcPrice = 0.00;
        for (Shop shop : shopList) {
            PriceDetail priceDetail = new PriceDetail();
            priceDetail.setPriceId(price.getId());
            priceDetail.setShopId(shop.getId());
            priceDetail.setTxm(shop.getTxm());
            priceDetail.setShopName(shop.getName());
            priceDetail.setNowPrice(shop.getJhPrice());
            priceDetail.setToPrice(shop.getToprice());
            priceDetail.setDiffPrice(shop.getToprice()-shop.getJhPrice());

            zcPrice += shop.getToprice()-shop.getJhPrice();

            priceDetailMapper.insert(priceDetail);
        }

        price.setZcPrice(zcPrice);

        priceMapper.updateById(price);


        return R.OK();
    }

    @Override
    public R getPriceById(Integer id) {
        Price price = priceMapper.selectById(id);

        QueryWrapper<PriceDetail> priceDetailQueryWrapper = new QueryWrapper<>();
        priceDetailQueryWrapper.lambda().eq(PriceDetail::getPriceId,id);
        List<PriceDetail> priceDetails = priceDetailMapper.selectList(priceDetailQueryWrapper);

        PriceInfoVo priceInfoVo = new PriceInfoVo();
        priceInfoVo.setPrice(price);
        priceInfoVo.setPriceDetailList(priceDetails);

        return R.OK(priceInfoVo);
    }

    @Override
    public R updateFlag(Price price) {
        Price price1 = priceMapper.selectById(price.getId());
        if(price1==null){
            return R.ERROR(500,"调价单不存在");
        }
        price1.setFlagId(price.getFlagId());

        String token = request.getHeader("token");
        Claims body = Jwts.parser().setSigningKey("123456").parseClaimsJws(token).getBody();
        Integer shId = body.get("userId", Integer.class);
        String shName = body.get("userName", String.class);

        price1.setShId(shId);
        price1.setShName(shName);
        price1.setShThing(price.getShThing());
        priceMapper.updateById(price1);


        //如果审核通过，发送同步消息
        if(price.getFlagId()==1){
            kafkaTemplate.send("kfk-price", JSON.toJSONString(price));
        }

        return R.OK();
    }

    @Override
    public R priceDetailList(PageInfoVo pageInfoVo) {
        Page<PriceDetail> priceDetailPage = new Page<>(pageInfoVo.getPageNum(), pageInfoVo.getPageSize());
        QueryWrapper<PriceDetail> priceDetailQueryWrapper = new QueryWrapper<>();
        if(pageInfoVo.getKeyWord()!=null){
            priceDetailQueryWrapper.like("shop_name",pageInfoVo.getKeyWord());
        }

        Page<PriceDetail> priceDetailPage1 = priceDetailMapper.selectPage(priceDetailPage, priceDetailQueryWrapper);

        return R.OK(priceDetailPage1);
    }

    @KafkaListener(topics = "kfk-price")
    public void sendMsg(String msg, Acknowledgment acknowledgment){

        System.out.println("已接受消息:"+msg);

        Price price = JSON.parseObject(msg, Price.class);

        List<PriceDetail> priceDetails = priceDetailMapper.selectList
                (new QueryWrapper<PriceDetail>().lambda().eq(PriceDetail::getPriceId, price.getId()));

        for (PriceDetail priceDetail : priceDetails) {
            Shop shop = shopMapper.selectById(priceDetail.getShopId());

            EsShop esShop = BeanUtil.toBean(shop, EsShop.class);
            elasticsearchRestTemplate.save(esShop);
        }

        acknowledgment.acknowledge();

        System.out.println("消息发送完成");

    }
}
